<script setup lang="ts">
import KoDataItem from "@/views/domain/kubeHud/views/components/ko-data-item/index.vue";
import KoBase from "@/views/domain/kubeHud/views/components/ko-workloads/ko-base.vue";
import koCheckRow from "@/views/domain/kubeHud/views/components/ko-workloads/ko-check-row.vue";

import KoKvTable from "@/views/domain/kubeHud/views/components/ko-workloads/ko-kv-table.vue";

import KoSpecBase from "@/views/domain/kubeHud/views/components/ko-workloads/ko-spec/ko-spec-base.vue";
import KoNodeSelector from "@/views/domain/kubeHud/views/components/ko-workloads/ko-spec/ko-node-selector.vue";
import KoPodScheduling from "@/views/domain/kubeHud/views/components/ko-workloads/ko-spec/ko-pod-scheduling.vue";
import KoTolerations from "@/views/domain/kubeHud/views/components/ko-workloads/ko-spec/ko-tolerations.vue";
import KoNetworking from "@/views/domain/kubeHud/views/components/ko-workloads/ko-spec/ko-networking.vue";
import KoSpecSecurity from "@/views/domain/kubeHud/views/components/ko-workloads/ko-spec/ko-spec-security.vue";
import KoUpgradeCommon from "@/views/domain/kubeHud/views/components/ko-workloads/ko-spec/ko-upgrade-common.vue";
import KoUpgradeJob from "@/views/domain/kubeHud/views/components/ko-workloads/ko-spec/ko-upgrade-job.vue";

import KoVolume from "@/views/domain/kubeHud/views/components/ko-workloads/ko-volume.vue";
import KoVolumeClaim from "@/views/domain/kubeHud/views/components/ko-workloads/ko-volume-claim.vue";
import KoContainer from "@/views/domain/kubeHud/views/components/ko-workloads/ko-container.vue";
import KoContainerEdit from "@/views/domain/kubeHud/views/components/ko-workloads/ko-container-edit.vue";
import KoContainerRow from "@/views/domain/kubeHud/views/components/ko-workloads/ko-container-row.vue";
import KoPorts from "@/views/domain/kubeHud/views/components/ko-workloads/ko-ports.vue";
import KoCommand from "@/views/domain/kubeHud/views/components/ko-workloads/ko-command.vue";
import KoEnvironment from "@/views/domain/kubeHud/views/components/ko-workloads/ko-environment.vue";
import KoResources from "@/views/domain/kubeHud/views/components/ko-workloads/ko-resources.vue";
import KoHealthCheck from "@/views/domain/kubeHud/views/components/ko-workloads/ko-health-check.vue";
import KoSecurityContext from "@/views/domain/kubeHud/views/components/ko-workloads/ko-security-context.vue";
import KoVolumeMount from "@/views/domain/kubeHud/views/components/ko-workloads/ko-volume-mount.vue";
import KoServiceAdd from "@/views/domain/kubeHud/views/components/ko-workloads/ko-service/ko-service-add.vue";
import KSection from "@/views/domain/kubeHud/views/components/k-section/index.vue";

import {
  ClusterInfo,
  ConfigMap,
  Container,
  DaemonSet,
  Deployment,
  Namespace,
  NodeInfo,
  PodSecurityContext,
  Secret,
  Service,
  StatefulSet,
  Volume
} from "@/views/domain/kubeHud/api/k8s";
import { WorkloadEditContainerType, WorkloadType } from "../provider";
import { useI18n } from "vue-i18n";
import { useFormRule } from "@/views/domain/kubeHud/utils/rules";
import { computed, ref } from "vue";
type WorkloadEntity = Deployment | StatefulSet | DaemonSet | any;

type Prop = {
  type?: WorkloadType;
  readonly?: boolean;
  nodeList?: NodeInfo[];
  namespaceList?: Namespace[];
  serviceList?: Service[];
  secretList?: Secret[];
  configMapList?: ConfigMap[];
  clusterList?: ClusterInfo[];
  volumeList?: Volume[];
};

const { t } = useI18n();
const { NumberRule } = useFormRule();

const props = defineProps<Prop>();
const workload = defineModel<WorkloadEntity>();

const editSpec = computed(() => {
  if (typeIsJob.value) {
    return workload.value.spec.jobTemplate.spec.template.spec;
  } else {
    return workload.value.spec.template.spec;
  }
});

const typeIsReplicateSet = computed(
  () =>
    props.type === WorkloadType.Deployment ||
    props.type === WorkloadType.StatefulSet
);

const typeIsJob = computed(
  () => props.type === WorkloadType.Job || props.type === WorkloadType.CronJob
);

const onToggleUseAffinity = (use: boolean) => {
  if (use) {
    workload.value.spec.template.spec.affinity = {};
  } else {
    delete workload.value.spec.template.spec.affinity;
  }
};

const onToggleTolerations = (use: boolean) => {
  if (use) {
    editSpec.value.tolerations = [];
  } else {
    delete editSpec.value.tolerations;
  }
};

const onToggleSecurityContext = (use: boolean) => {
  if (use) {
    editSpec.value.securityContext = {
      seLinuxOptions: {}
    } as PodSecurityContext;
  } else {
    delete editSpec.value.securityContext;
  }
};

const editContainer = ref<Container>();
const editContainerType = ref<WorkloadEditContainerType>();
const editDialogVisible = ref(false);

const onShouldCreateContainer = (ctype: WorkloadEditContainerType) => {
  editContainer.value = { name: "" };
  editContainerType.value = ctype;
  editDialogVisible.value = true;
};

const onSubmitCreateContainer = () => {
  if (!editContainer.value) return;
  if (editContainerType.value === WorkloadEditContainerType.Standard) {
    const exists = editSpec.value.containers?.find(
      c => c.name === editContainer.value?.name
    );
    if (!exists) {
      editSpec.value.containers.push(editContainer.value);
    }
  } else if (editContainerType.value === WorkloadEditContainerType.Init) {
    const exists = editSpec.value.initContainers?.find(
      c => c.name === editContainer.value?.name
    );
    if (!exists) {
      editSpec.value.initContainers.push(editContainer.value);
    }
  }

  closeContainerEditWindow();
};

const closeContainerEditWindow = () => {
  editDialogVisible.value = false;
  editContainerType.value = undefined;
  editContainer.value = undefined;
};

const onShouldEditContainer = (
  c: Container,
  type: WorkloadEditContainerType
) => {
  editContainerType.value = type;
  editContainer.value = c;
  editDialogVisible.value = true;
};

const onShouldDeleteContainer = (
  ctype: WorkloadEditContainerType,
  index: number
) => {
  if (ctype === WorkloadEditContainerType.Standard) {
    editSpec.value.containers.splice(index, 1);
  } else if (ctype === WorkloadEditContainerType.Init) {
    editSpec.value.initContainers.splice(index, 1);
  }
};
</script>

<template>
  <div class="pod-edit-row">
    <k-section
      v-if="typeIsReplicateSet"
      :title="$t('business.workload.replicas')"
    >
      <ko-data-item
        v-model:model-value="workload.spec.replicas"
        class="w-full"
        :disabled="readonly"
        itemType="number"
        :default="1"
        :min="0"
        :max="1000"
      />
    </k-section>

    <k-section :title="'容器组'" type="simple">
      <el-dialog
        v-model="editDialogVisible"
        title="新建容器"
        width="80%"
        class="container-edit-dialog"
        append-to-body
        :before-close="closeContainerEditWindow"
      >
        <ko-container-edit
          v-if="editContainer"
          v-model:container="editContainer"
          v-model:workload-metadata="workload.metadata"
          :namespace="workload.metadata.namespace"
          :readonly="readonly"
          :type="editContainerType"
          :config-map-list="configMapList"
          :volume-list="volumeList"
          :secret-list="secretList"
        />
        <template #footer>
          <div>
            <el-button type="info">取消</el-button>
            <el-button type="primary" @click="onSubmitCreateContainer">
              确认
            </el-button>
          </div>
        </template>
      </el-dialog>
      <ko-container-row
        v-for="(container, idx) in editSpec.containers ?? []"
        :key="`standard_${idx}`"
        :container="container"
        @edit="
          onShouldEditContainer(container, WorkloadEditContainerType.Standard)
        "
        @delete="
          onShouldDeleteContainer(WorkloadEditContainerType.Standard, idx)
        "
      />
      <ko-container-row
        v-for="(container, idx) in editSpec.initContainers ?? []"
        :key="`init_${idx}`"
        :container="container"
        @edit="onShouldEditContainer(container, WorkloadEditContainerType.Init)"
        @delete="onShouldDeleteContainer(WorkloadEditContainerType.Init, idx)"
      />
      <ko-container-row
        create-trigger
        @should-create="onShouldCreateContainer"
      />
    </k-section>

    <k-section
      :title="$t('business.workload.upgrade_policy')"
      check
      check-on-body
      :check-model="true"
    >
      <ko-upgrade-job
        v-if="typeIsJob"
        :readonly="readonly"
        :upgradePolicyParentObj="workload.spec"
        :resourceType="type"
      />
      <ko-upgrade-common
        v-else
        v-model:spec="workload.spec"
        :readonly="readonly"
        :resource-type="type"
      />
    </k-section>

    <k-section
      v-if="false"
      :title="$t('business.workload.node_schedule')"
      check
      check-on-body
      :check-model="true"
    >
      <ko-node-selector
        ref="ko_node_scheduling"
        v-model:spec="editSpec"
        :readonly="readonly"
        :node-list="nodeList"
      />
    </k-section>

    <k-section
      :title="'调度规则'"
      check
      check-on-body
      :check-model="workload.spec.template.spec.affinity"
      @check-changed="onToggleUseAffinity"
    >
      <ko-pod-scheduling
        v-model:spec="editSpec"
        :readonly="readonly"
        :namespace-list="namespaceList"
      />
    </k-section>

    <k-section
      v-if="false"
      :title="$t('business.workload.toleration')"
      check
      check-on-body
      :check-model="editSpec.tolerations"
      @check-changed="onToggleTolerations"
    >
      <ko-tolerations
        ref="ko_toleration"
        :readonly="readonly"
        :tolerations="editSpec.tolerations"
      />
    </k-section>

    <k-section v-if="false" :title="$t('business.workload.network')">
      <ko-networking
        ref="ko_networking"
        v-model:pod-spec="editSpec"
        :readonly="readonly"
      />
    </k-section>

    <k-section
      :title="$t('business.workload.pod_security_context')"
      check
      check-on-body
      :check-model="editSpec.securityContext"
      @check-changed="onToggleSecurityContext"
    >
      <ko-security-context
        ref="ko_spec_security"
        v-model:security-context="editSpec.securityContext"
        :readonly="readonly"
      />
    </k-section>
  </div>
</template>
<style lang="scss">
.pod-edit-row {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 15px;
}
.row-title {
  font-size: 14px;
  font-weight: 600;
  margin-bottom: 10px;
}

.container-edit-dialog {
  --el-dialog-margin-top: 1vh;
  max-height: calc(100vh - 1vh - 50px);
  display: flex;
  flex-direction: column;
  > .el-dialog__body {
    overflow: auto;
    flex: 1;
  }
}
</style>
